package com.bzsg.rightsManagementSystem.util

import com.bzsg.rightsManagementSystem.pojo.PersonUser
import io.jsonwebtoken.Claims
import io.jsonwebtoken.ExpiredJwtException
import io.jsonwebtoken.Jwts
import io.jsonwebtoken.SignatureAlgorithm
import org.springframework.stereotype.Component


import java.util.*


@Component
object JwtTokenUtil {
    const val TOKEN_HEADER = "Authorization"
    const val TOKEN_PREFIX = "Bearer"

    /**
     * 秘钥
     */
    private const val SECRET = "happyDay"
    private const val ISS = "bzsg"

    /**
     * 过期时间是3600秒，既是1个小时
     */
    private const val EXPIRATION = (60 * 60 * 1000).toLong()
    /**
     * 创建Token
     * @return token
     */
    fun createToken(user: PersonUser): String {
        val claims: MutableMap<String, Any> = HashMap()
        claims["account"] = user.account
        return doGenerateToken(claims, user.userName)
    }

    /**
     * 从数据声明生成令牌
     *
     * @param claims 数据声明
     * @return 令牌
     */
    private fun doGenerateToken(claims: Map<String, Any>, subject: String): String {
        val expiration = Date(System.currentTimeMillis() + EXPIRATION)
        return TOKEN_PREFIX + Jwts.builder() //签发时间
            .setIssuedAt(Date()) //签发者
            .setIssuer(ISS) //声明
            .setClaims(claims) //过期时间
            .setExpiration(expiration) //面向用户
            .setSubject(subject)
            .signWith(SignatureAlgorithm.HS256, SECRET)
            .compact()
    }

    /**
     * 获取用户名
     * @param token
     * @return  username
     */
    fun getUsername(token: String): String?{
        return try {
            getTokenBody(token).subject
        } catch (e: ExpiredJwtException) {
            // TODO: handle exception
            null
        }
    }
    /**
     * 解析token
     * @param token
     * @return
     */
    private fun getTokenBody(token: String): Claims {
        val claims= try {
            Jwts.parser()
                .setSigningKey(SECRET) // 设置标识名
                .parseClaimsJws(token) //解析token
                .body
        } catch (e: ExpiredJwtException) {
            e.claims
        }
        return claims
    }

    /**
     * token是否过期
     * @param token
     * @return true or false
     */
    private fun isExpiration(token: String): Boolean {
        return getTokenBody(token).expiration.before(Date())
    }

    /**
     * 刷新token
     * @param token
     * @return token
     */
    fun refreshToken(token: String): String? {
        val refreshToken = try {
            val claims= getTokenBody(token)
            claims["create"] = Date()
            doGenerateToken(claims, claims.subject)
        } catch (e: Exception) {
            null
        }
        return refreshToken
    }

    /**
     * 验证Token
     * @return true or false
     */
    fun validateToken(token: String, username: String): Boolean {
        val subject = getUsername(token)
        return subject == username && !isExpiration(token)
    }
}